package com.fish.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fish.common.exception.BusinessException;
import com.fish.common.result.ResultCode;
import com.fish.dao.mapper.OrganizationMapper;
import com.fish.dao.mapper.TitleMapper;
import com.fish.dao.mapper.UserMapper;
import com.fish.dao.mapper.UserOrganizationMapper;
import com.fish.model.dto.OrganizationDTO;
import com.fish.model.dto.UserOrganizationDTO;
import com.fish.model.entity.Organization;
import com.fish.model.entity.Title;
import com.fish.model.entity.User;
import com.fish.model.entity.UserOrganization;
import com.fish.model.vo.OrganizationVO;
import com.fish.model.vo.UserOrganizationVO;
import com.fish.model.vo.DictDataVO;
import com.fish.service.DictDataService;
import com.fish.service.OrganizationService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 组织服务实现类
 */
@Slf4j
@Service
public class OrganizationServiceImpl implements OrganizationService {
    
    @Autowired
    private OrganizationMapper organizationMapper;
    
    @Autowired
    private UserOrganizationMapper userOrganizationMapper;
    
    @Autowired
    private UserMapper userMapper;
    
    @Autowired
    private TitleMapper titleMapper;
    
    @Autowired
    private DictDataService dictDataService;
    
    // 组织类型字典缓存
    private Map<String, String> orgTypeMap = new HashMap<>();
    // 头衔字典缓存
    private Map<String, String> titleMap = new HashMap<>();
    
    @Override
    public List<OrganizationVO> getOrganizationTree() {
        // 获取所有组织
        List<Organization> allOrgs = organizationMapper.selectList(
            new LambdaQueryWrapper<Organization>()
                .eq(Organization::getStatus, 1)
                .orderByAsc(Organization::getOrderNum)
        );
        
        // 转换为VO并构建树形结构
        List<OrganizationVO> orgVOList = allOrgs.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
        
        return buildTree(orgVOList, 0L);
    }
    
    @Override
    public List<OrganizationVO> getOrganizationsByParentId(Long parentId) {
        List<Organization> orgs = organizationMapper.selectList(
            new LambdaQueryWrapper<Organization>()
                .eq(Organization::getParentId, parentId)
                .eq(Organization::getStatus, 1)
                .orderByAsc(Organization::getOrderNum)
        );
        
        return orgs.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }
    
    @Override
    public OrganizationVO getOrganizationById(Long id) {
        Organization org = organizationMapper.selectById(id);
        if (org == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXIST.getCode(), "组织不存在");
        }
        return convertToVO(org);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrganizationVO createOrganization(OrganizationDTO dto) {
        // 检查组织编码是否已存在
        LambdaQueryWrapper<Organization> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Organization::getOrgCode, dto.getOrgCode());
        if (organizationMapper.selectCount(wrapper) > 0) {
            throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), "组织编码已存在");
        }
        
        Organization org = new Organization();
        BeanUtil.copyProperties(dto, org);
        
        organizationMapper.insert(org);
        log.info("创建组织成功，组织名称：{}", org.getOrgName());
        
        return convertToVO(org);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public OrganizationVO updateOrganization(OrganizationDTO dto) {
        if (dto.getId() == null) {
            throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), "组织ID不能为空");
        }
        
        Organization org = organizationMapper.selectById(dto.getId());
        if (org == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXIST.getCode(), "组织不存在");
        }
        
        // 检查组织编码是否重复
        if (!org.getOrgCode().equals(dto.getOrgCode())) {
            LambdaQueryWrapper<Organization> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(Organization::getOrgCode, dto.getOrgCode());
            wrapper.ne(Organization::getId, dto.getId());
            if (organizationMapper.selectCount(wrapper) > 0) {
                throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), "组织编码已存在");
            }
        }
        
        BeanUtil.copyProperties(dto, org, "id", "createTime", "createBy");
        organizationMapper.updateById(org);
        
        log.info("更新组织成功，组织ID：{}", org.getId());
        return convertToVO(org);
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteOrganization(Long id) {
        // 检查是否有子组织
        LambdaQueryWrapper<Organization> childWrapper = new LambdaQueryWrapper<>();
        childWrapper.eq(Organization::getParentId, id);
        if (organizationMapper.selectCount(childWrapper) > 0) {
            throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), "该组织下还有子组织，无法删除");
        }
        
        // 检查是否有成员
        LambdaQueryWrapper<UserOrganization> memberWrapper = new LambdaQueryWrapper<>();
        memberWrapper.eq(UserOrganization::getOrgId, id);
        memberWrapper.eq(UserOrganization::getStatus, 1);
        if (userOrganizationMapper.selectCount(memberWrapper) > 0) {
            throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), "该组织下还有成员，无法删除");
        }
        
        organizationMapper.deleteById(id);
        log.info("删除组织成功，组织ID：{}", id);
    }
    
    @Override
    public List<UserOrganizationVO> getOrganizationMembers(Long orgId) {
        LambdaQueryWrapper<UserOrganization> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserOrganization::getOrgId, orgId);
        wrapper.eq(UserOrganization::getStatus, 1);
        List<UserOrganization> userOrgs = userOrganizationMapper.selectList(wrapper);
        
        return userOrgs.stream()
            .map(this::convertToUserOrganizationVO)
            .collect(Collectors.toList());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void addOrganizationMember(UserOrganizationDTO dto) {
        // 检查用户是否已在任何组织中（一个用户只能属于一个组织）
        LambdaQueryWrapper<UserOrganization> existsWrapper = new LambdaQueryWrapper<>();
        existsWrapper.eq(UserOrganization::getUserId, dto.getUserId());
        existsWrapper.eq(UserOrganization::getStatus, 1);
        
        UserOrganization existingUserOrg = userOrganizationMapper.selectOne(existsWrapper);
        if (existingUserOrg != null) {
            // 获取已存在组织的名称
            Organization existingOrg = organizationMapper.selectById(existingUserOrg.getOrgId());
            String orgName = existingOrg != null ? existingOrg.getOrgName() : "未知组织";
            throw new BusinessException(ResultCode.PARAM_ERROR.getCode(), 
                "该用户已在组织【" + orgName + "】中，一个用户只能属于一个组织");
        }
        
        UserOrganization userOrg = new UserOrganization();
        BeanUtil.copyProperties(dto, userOrg);
        userOrg.setStatus(1);
        userOrg.setIsMain(1); // 既然只能有一个组织，默认设置为主组织
        if (userOrg.getJoinDate() == null) {
            userOrg.setJoinDate(LocalDate.now());
        }
        
        userOrganizationMapper.insert(userOrg);
        log.info("添加组织成员成功，用户ID：{}，组织ID：{}，头衔：{}", dto.getUserId(), dto.getOrgId(), dto.getTitleValue());
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeOrganizationMember(Long userId, Long orgId) {
        LambdaQueryWrapper<UserOrganization> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserOrganization::getUserId, userId);
        wrapper.eq(UserOrganization::getOrgId, orgId);
        
        UserOrganization userOrg = userOrganizationMapper.selectOne(wrapper);
        if (userOrg != null) {
            userOrg.setStatus(0);
            userOrg.setLeaveDate(LocalDate.now());
            userOrganizationMapper.updateById(userOrg);
            log.info("移除组织成员成功，用户ID：{}，组织ID：{}", userId, orgId);
        }
    }
    
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateUserOrganization(UserOrganizationDTO dto) {
        LambdaQueryWrapper<UserOrganization> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserOrganization::getUserId, dto.getUserId());
        wrapper.eq(UserOrganization::getOrgId, dto.getOrgId());
        
        UserOrganization userOrg = userOrganizationMapper.selectOne(wrapper);
        if (userOrg == null) {
            throw new BusinessException(ResultCode.DATA_NOT_EXIST.getCode(), "用户组织关系不存在");
        }
        
        BeanUtil.copyProperties(dto, userOrg, "userId", "orgId", "createTime");
        userOrganizationMapper.updateById(userOrg);
        
        log.info("更新用户组织关系成功，用户ID：{}，组织ID：{}，头衔：{}", dto.getUserId(), dto.getOrgId(), dto.getTitleValue());
    }
    
    @Override
    public List<OrganizationVO> getUserOrganizations(Long userId) {
        LambdaQueryWrapper<UserOrganization> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserOrganization::getUserId, userId);
        wrapper.eq(UserOrganization::getStatus, 1);
        List<UserOrganization> userOrgs = userOrganizationMapper.selectList(wrapper);
        
        List<Long> orgIds = userOrgs.stream()
            .map(UserOrganization::getOrgId)
            .collect(Collectors.toList());
        
        if (orgIds.isEmpty()) {
            return new ArrayList<>();
        }
        
        List<Organization> orgs = organizationMapper.selectBatchIds(orgIds);
        return orgs.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }
    
    @Override
    public List<Long> getOrganizationIdsWithChildren(Long orgId) {
        List<Long> result = new ArrayList<>();
        result.add(orgId);
        collectChildrenIds(orgId, result);
        return result;
    }
    
    @Override
    public List<Long> getUserIdsByOrgId(Long orgId, boolean includeChildren) {
        List<Long> orgIds;
        if (includeChildren) {
            orgIds = getOrganizationIdsWithChildren(orgId);
        } else {
            orgIds = List.of(orgId);
        }
        
        LambdaQueryWrapper<UserOrganization> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(UserOrganization::getOrgId, orgIds);
        wrapper.eq(UserOrganization::getStatus, 1);
        
        List<UserOrganization> userOrgs = userOrganizationMapper.selectList(wrapper);
        return userOrgs.stream()
            .map(UserOrganization::getUserId)
            .distinct()
            .collect(Collectors.toList());
    }
    
    /**
     * 递归收集子组织ID
     */
    private void collectChildrenIds(Long parentId, List<Long> result) {
        LambdaQueryWrapper<Organization> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Organization::getParentId, parentId);
        List<Organization> children = organizationMapper.selectList(wrapper);
        
        for (Organization child : children) {
            result.add(child.getId());
            collectChildrenIds(child.getId(), result);
        }
    }
    
    /**
     * 构建树形结构
     */
    private List<OrganizationVO> buildTree(List<OrganizationVO> allNodes, Long parentId) {
        return allNodes.stream()
            .filter(node -> parentId.equals(node.getParentId()))
            .peek(node -> {
                List<OrganizationVO> children = buildTree(allNodes, node.getId());
                node.setChildren(children);
                node.setChildCount(children.size());
                
                // 统计成员数量
                LambdaQueryWrapper<UserOrganization> wrapper = new LambdaQueryWrapper<>();
                wrapper.eq(UserOrganization::getOrgId, node.getId());
                wrapper.eq(UserOrganization::getStatus, 1);
                node.setMemberCount(Math.toIntExact(userOrganizationMapper.selectCount(wrapper)));
            })
            .collect(Collectors.toList());
    }
    
    /**
     * 转换为VO
     */
    private OrganizationVO convertToVO(Organization org) {
        OrganizationVO vo = new OrganizationVO();
        BeanUtil.copyProperties(org, vo);
        
        // 从字典获取组织类型名称
        String orgTypeName = getOrgTypeName(String.valueOf(org.getOrgType()));
        vo.setOrgTypeName(orgTypeName != null ? orgTypeName : "未知");
        
        // 获取负责人姓名
        if (org.getLeaderId() != null) {
            User leader = userMapper.selectById(org.getLeaderId());
            if (leader != null) {
                vo.setLeaderName(leader.getNickname());
            }
        }
        
        return vo;
    }
    
    /**
     * 获取组织类型名称（从字典）
     */
    private String getOrgTypeName(String orgTypeValue) {
        // 如果缓存为空，加载字典数据
        if (orgTypeMap.isEmpty()) {
            loadOrgTypeDictCache();
        }
        return orgTypeMap.get(orgTypeValue);
    }
    
    /**
     * 加载组织类型字典缓存
     */
    private void loadOrgTypeDictCache() {
        try {
            List<DictDataVO> dictList = dictDataService.getByType("sys_org_type");
            orgTypeMap = dictList.stream()
                .collect(Collectors.toMap(
                    DictDataVO::getDictValue,
                    DictDataVO::getDictLabel,
                    (v1, v2) -> v1
                ));
        } catch (Exception e) {
            log.error("加载组织类型字典失败", e);
        }
    }
    
    /**
     * 获取头衔名称（从字典）
     */
    private String getTitleName(String titleValue) {
        // 如果缓存为空，加载字典数据
        if (titleMap.isEmpty()) {
            loadTitleDictCache();
        }
        return titleMap.get(titleValue);
    }
    
    /**
     * 加载头衔字典缓存
     */
    private void loadTitleDictCache() {
        try {
            List<DictDataVO> dictList = dictDataService.getByType("sys_title");
            titleMap = dictList.stream()
                .collect(Collectors.toMap(
                    DictDataVO::getDictValue,
                    DictDataVO::getDictLabel,
                    (v1, v2) -> v1
                ));
        } catch (Exception e) {
            log.error("加载头衔字典失败", e);
        }
    }
    
    /**
     * 转换为用户组织关系VO
     */
    private UserOrganizationVO convertToUserOrganizationVO(UserOrganization userOrg) {
        UserOrganizationVO vo = new UserOrganizationVO();
        
        // 设置关系ID
        vo.setId(userOrg.getId());
        
        // 获取用户信息
        User user = userMapper.selectById(userOrg.getUserId());
        if (user != null) {
            vo.setUserId(user.getId());
            vo.setUsername(user.getUsername());
            vo.setNickname(user.getNickname());
            vo.setAvatar(user.getAvatar());
        }
        
        // 获取组织信息
        Organization org = organizationMapper.selectById(userOrg.getOrgId());
        if (org != null) {
            vo.setOrgId(org.getId());
            vo.setOrgName(org.getOrgName());
            vo.setOrgCode(org.getOrgCode());
        }
        
        // 获取头衔信息（从字典获取）
        if (userOrg.getTitleValue() != null && !userOrg.getTitleValue().isEmpty()) {
            vo.setTitleValue(userOrg.getTitleValue());
            
            // 从字典获取头衔名称
            String titleName = getTitleNameFromDict(userOrg.getTitleValue());
            vo.setTitleName(titleName != null ? titleName : "未知头衔");
        }
        
        vo.setIsMain(userOrg.getIsMain());
        vo.setJoinDate(userOrg.getJoinDate());
        vo.setStatus(userOrg.getStatus());
        vo.setRemark(userOrg.getRemark());
        
        return vo;
    }
    
    /**
     * 从字典获取头衔名称
     */
    private String getTitleNameFromDict(String titleValue) {
        // 如果缓存为空，加载字典数据
        if (titleMap.isEmpty()) {
            loadTitleDictCache();
        }
        return titleMap.get(titleValue);
    }
}

